package com.loveyukari.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.loveyukari.common.exception.InternalException;
import com.loveyukari.utils.HttpUtils;
import com.loveyukari.utils.ImageUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
*
*yangshaohua
*2017年2月16日下午1:00:20
**/
@Service
public class RandomService {
	
	private Logger log = LoggerFactory.getLogger(RandomService.class);
	
	public List<Integer> randomInt(int max,int size,int status){
		Random random = new Random();
		List<Integer> list = new ArrayList<Integer>();
		if (status == 2 && size > max){
			size = max;
		}
		while(list.size() < size){
			int r = random.nextInt(max);
			if (status == 1 && list.contains(r)){
				continue;
			}
			list.add(r);
		}
		return list;
	}

	private String answerfloor = "https://yuba.douyu.com/answer/answerfloor";
	public Set<JSONObject> randomYubaNumber(String url,String sizeStr,int status) throws Exception{
		if (StringUtils.isBlank(url)){
			throw new InternalException("请输入帖子链接");
		}
		int size = 0;
		try {
			size = Integer.parseInt(sizeStr);
		} catch (NumberFormatException e1) {
			throw new InternalException("抽奖人数输入有误");
		}
		Set<JSONObject> set = new HashSet<JSONObject>();
		if (size <= 0) {
			return set;
		}
		String content = null;
		try {
			content = sendUrl(url, null);
		} catch (InternalException e) {
			throw new InternalException("获取帖子信息失败，请确认链接是否有效");
		}
		String qid = getAttr(content, "YUBA.environment.phpVariable.userCenterQuestionDetailQid");
		if (qid == null){
			throw new InternalException("无法获取帖子ID，请确认输入链接是鱼吧帖子");
		}
		int replyCount = Integer.parseInt(getAttr(content, "YUBA.environment.phpVariable.postReplyCount"));
		if (replyCount != 0){
			Random random = new Random();
			Map<Integer,JSONArray> cachePageContent = new HashMap<Integer,JSONArray>();
			if (status == 1){
				if (size > replyCount){
					throw new InternalException("抽奖人数超过回复数");
				}
				while(set.size()<size){
					int r = random.nextInt(replyCount);
					int page = r/30+1;
					int pageNumber = r%30;
					JSONArray jsonArray = cachePageContent.get(page);
					if (jsonArray == null){
						String pageContent = null;
						try {
							pageContent = sendUrl(answerfloor+"?qid="+qid+"&page="+page, null);
						} catch (InternalException e) {
							throw new InternalException("获取楼层信息失败，请重试");
						}
						JSONObject json = JSONObject.fromObject(pageContent);
						if ("ok".equals(json.getString("status"))){
							jsonArray = parsePageContent(json.getJSONObject("data").getString("content"));
							cachePageContent.put(page, jsonArray);
						} else {
							throw new InternalException("获取楼层信息失败，请重试");
						}
					}
					set.add(jsonArray.getJSONObject(pageNumber));
				}
			} else if (status == 2){
				int page = (replyCount-1)/30+1;
				Map<String, JSONArray> nameMap = new HashMap<String,JSONArray>();
				List<String> nameList = new ArrayList<String>();
				for (int i = 1; i <= page; i++) {
					String pageContent;
					try {
						pageContent = sendUrl(answerfloor+"?qid="+qid+"&page="+i, null);
					} catch (InternalException e) {
						throw new InternalException("获取楼层信息失败，请重试");
					}
					JSONObject json = JSONObject.fromObject(pageContent);
					if ("ok".equals(json.getString("status"))){
						JSONArray jsonArray = parsePageContent(json.getJSONObject("data").getString("content"));
						for (int j = 0; j < jsonArray.size(); j++) {
							JSONObject jsonObject = jsonArray.getJSONObject(j);
							String name = jsonObject.getString("name");
							JSONArray array = nameMap.get(name);
							if (array == null){
								array = new JSONArray();
								nameMap.put(name, array);
								nameList.add(name);
							}
							array.add(jsonObject);
						}
					} else {
						throw new InternalException("获取楼层信息失败，请重试");
					}
					if (size > nameMap.size()){
						throw new InternalException("抽奖人数超过总人数");
					}
				}
				while(set.size()<size){
					int r = random.nextInt(nameMap.size());
					String name = nameList.get(r);
					JSONArray jsonArray = nameMap.get(name);
					set.add(jsonArray.getJSONObject(0));
				}
				
			}
		}
		return set;
	}
	
	private String sendUrl(String url,Map<String,Object>param) throws Exception{
		int errorCount = 0;
		while (true){
			try {
				String send = HttpUtils.sendGet(url,param);
				return send;
			} catch (Exception e) {
				errorCount++;
				if (errorCount >= 3){
					throw e;
				}
			}
		}
	}
	
	private String getAttr(String content,String key){
		String[] split = content.split(key);
		StringBuilder sb = new StringBuilder();
		for (int i = 1; i < split.length; i++) {
			String str = split[i].substring(0, split[i].indexOf(";")).replace("'", "").replace("\"", "").replace("=", "").replace(" ", "");
			sb.append(str).append(",");
		}
		return sb.substring(0, sb.length()-1);
	}
	
	private JSONArray parsePageContent(String content){
		List<String> list = new ArrayList<String>();
		String[] split = content.split("<dl class=\"reply-dl clearfix\"");
		for (int i = 0; i < split.length; i++) {
			if (split[i].contains("</dl>")){
				list.add(split[i].split("</dl>")[0]);
			}
		}
		JSONArray jsonArray = new JSONArray();
		for (String dl : list) {
			int nameStart = dl.indexOf(">",dl.indexOf("<a class=\"user-name"))+1;
			int nameEnd = dl.indexOf("</a>",nameStart);
			String name = dl.substring(nameStart, nameEnd).replace(" ", "").replace("\n", "");
			int txtStart = dl.indexOf(">",dl.indexOf("<div class=\"reply-content"))+1;
			int txtEnd = dl.indexOf("</div>",txtStart);
			String txt = dl.substring(txtStart, txtEnd).replace("\n", "");
			int numberStart = dl.indexOf(">",dl.indexOf("id=\"replyFloor"))+1;
			int numberEnd = dl.indexOf("</span>",numberStart);
			String number = dl.substring(numberStart, numberEnd).replace(" ", "").replace("\n", "");
			int dateStart = dl.indexOf(">",dl.indexOf("<span",numberEnd))+1;
			int dateEnd = dl.indexOf("</span>",dateStart);
			String dateStr = dl.substring(dateStart, dateEnd).replace("\n", "").replace("<!--发布于-->", "");
			String[] dates = dateStr.split(" ");
			dateStr="";
			for (int i = 0; i < dates.length; i++) {
				if (StringUtils.isNotBlank(dates[i])){
					if (dateStr.length() != 0){
						dateStr = dateStr + " ";
					}
					dateStr = dateStr + dates[i];
				}
			}
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("name", name);
			jsonObject.put("txt", txt);
			jsonObject.put("number", number);
			jsonObject.put("date", dateStr);
			jsonArray.add(jsonObject);
		}
		return jsonArray;
	}
	
	
	private JSONArray authArray = new JSONArray();
	
	public JSONObject randomBilibiliComment(int av,int drawSize){
		log.info("random bilibili comment av"+av+", size "+drawSize);
		String url = "https://api.bilibili.com/x/v2/reply?type=1&oid="+av+"&pn=";
		JSONObject resultJson = new JSONObject();
		int index = 1;
		while (true) {
			log.info("random bilibili comment index "+index);
			JSONObject json = null;
			while(true){
				try {
					String result = HttpUtils.sendGet(url+index);
					json = JSONObject.fromObject(result);
					if (json != null && json.optInt("code",-1) == 0){
						break;
					}
				} catch (Exception e) {
					log.error(e.getMessage(),e);
				}
			}
			JSONObject data = json.optJSONObject("data");
			JSONObject page = data.optJSONObject("page");
			JSONArray replies = data.optJSONArray("replies");
			for (int i = 0; i < replies.size(); i++) {
				JSONObject reply = replies.optJSONObject(i);
				int mid = reply.optInt("mid");
				if (resultJson.containsKey(mid)){
					continue;
				}
				int floor = reply.optInt("floor");
				long ctime = reply.optLong("ctime");
				String time = sdf.format(new Date(ctime*1000));
				JSONObject member = reply.optJSONObject("member");
				JSONObject content = reply.optJSONObject("content");
				String message = content.optString("message");
				String uname = member.optString("uname");
				String avatar = member.optString("avatar");
				JSONObject commentJson = new JSONObject();
				commentJson.put("mid", mid);
				commentJson.put("floor", floor);
				commentJson.put("time", time);
				commentJson.put("uname", uname);
				commentJson.put("avatar", avatar);
				commentJson.put("message", message);
				commentJson.put("page", index);
				commentJson.put("index", i);
				resultJson.put(mid, commentJson);
			}
			int count = page.optInt("count");
			int num = page.optInt("num");
			int size = page.optInt("size");
			if (num * size > count){
				break;
			}
			index++;
		}
		JSONObject result = new JSONObject();
		Random random = new Random();
		JSONArray names = resultJson.names();
		result.put("total", names.size());
		JSONArray authArray = new JSONArray();
		for (int i = 0; i < drawSize; i++) {
			int nameIndex = random.nextInt(names.size());
			String mid = names.optString(nameIndex);
			JSONObject json = resultJson.optJSONObject(mid);
			log.info(json.toString());
			String avatar = json.optString("avatar");
			String imgBase64 = ImageUtils.getImageBase64(avatar);
			if (StringUtils.isBlank(imgBase64)){
				imgBase64 = ImageUtils.getImageBase64(avatar);
			}
			String imgType = avatar.substring(avatar.lastIndexOf("."));
			json.put("imgType", imgType);
			json.put("imgBase64", imgBase64);
			authArray.add(json);
			resultJson.remove(mid);
		}
		result.put("authArray", authArray);
		this.authArray = authArray;
		return result;
	}
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public JSONObject randomBilibiliCommentRepeat(int av,int drawSize){
		log.info("random bilibili comment av"+av+", size "+drawSize);
		String url = "https://api.bilibili.com/x/v2/reply?type=1&oid="+av+"&pn=";
		JSONObject resultJson = new JSONObject();
		JSONObject page = null;
		while(true){
			try {
				String result = HttpUtils.sendGet(url);
				JSONObject json = JSONObject.fromObject(result);
				if (json != null && json.optInt("code",-1) == 0){
					page = json.optJSONObject("data").optJSONObject("page");
					break;
				}
			} catch (Exception e) {
				log.error(e.getMessage(),e);
			}
		}
		Random random = new Random();
		while (true){
			int resultSize = resultJson.names().size();
			log.info("random bilibili  result size "+resultSize);
			if (resultSize >= drawSize){
				break;
			}
			int count = page.optInt("count",0);
			int size = page.optInt("size",20);
			int pageIndex = random.nextInt(count/size)+1;
			while(true){
				try {
					String result = HttpUtils.sendGet(url+pageIndex);
					JSONObject json = JSONObject.fromObject(result);
					if (json != null && json.optInt("code",-1) == 0){
						JSONObject data = json.optJSONObject("data");
						page = data.optJSONObject("page");
						JSONArray replies = data.optJSONArray("replies");
						int i = random.nextInt(page.optInt("size",20));
						JSONObject reply = replies.optJSONObject(i);
						int mid = reply.optInt("mid");
						if (!resultJson.containsKey(mid)){
							int floor = reply.optInt("floor");
							long ctime = reply.optLong("ctime");
							String time = sdf.format(new Date(ctime*1000));
							JSONObject member = reply.optJSONObject("member");
							JSONObject content = reply.optJSONObject("content");
							String message = content.optString("message");
							String uname = member.optString("uname");
							String avatar = member.optString("avatar");
							JSONObject commentJson = new JSONObject();
							commentJson.put("mid", mid);
							commentJson.put("floor", floor);
							commentJson.put("time", time);
							commentJson.put("uname", uname);
							commentJson.put("avatar", avatar);
							commentJson.put("message", message);
							commentJson.put("page", pageIndex);
							commentJson.put("index", i);
							resultJson.put(mid, commentJson);
						}
						break;
					}
				} catch (Exception e) {
					log.error(e.getMessage(),e);
				}
			}
		}
		JSONArray names = resultJson.names();
		JSONArray authArray = new JSONArray();
		for (int i = 0; i < names.size(); i++) {
			JSONObject json = resultJson.optJSONObject(names.getString(i));
			log.info(json.toString());
			String avatar = json.optString("avatar");
			String imgBase64 = ImageUtils.getImageBase64(avatar);
			if (StringUtils.isBlank(imgBase64)){
				imgBase64 = ImageUtils.getImageBase64(avatar);
			}
			String imgType = avatar.substring(avatar.lastIndexOf("."));
			json.put("imgType", imgType);
			json.put("imgBase64", imgBase64);
			authArray.add(json);
		}
		JSONObject result = new JSONObject();
		result.put("total", page.optInt("count"));
		result.put("authArray", authArray);
		this.authArray = authArray;
		return result;
	}

	public JSONArray getAuthArray() {
		return authArray;
	}
	
	
	
	
}
